#include "gus2_config.h"
#include "memserializer.h"
#include "bytearray.h"
#include <string.h>

void byte_array_init(bytearray_t* byarray, u8* buff, int size)
{
	byarray->data = buff;
	byarray->len = 0;
	byarray->size = size;
    byarray->self_ival = 0;
}
void byte_array_segment_init(bytearray_t* ba, bytearray_t* segment, int size) {
	if (size == -1) {
		size = ba->size - ba->len;
	}
	byte_array_init(segment, ba->data + ba->len, size);
	if (size > ba->size - ba->len) {
		segment->size = ba->size - ba->len;
	}
}
void byte_array_segment_merge(bytearray_t* ba, bytearray_t* segment) {

	ba->len += segment->len;
	segment->data = NULL;
	segment->len = 0;
	segment->size = 0;
	segment->self_ival = 0;
}
int byte_array_preset_cnt(bytearray_t* ba) {
	int len = ba->len;
	int index = 0;
	ba->len = 0;
	index = byte_array_serial(ba, "w", len >2 ? len-2: len);
	if (len != 0) {
		ba->len = len;
	}
	return index;
}
#if GUS2_ENABLE_MALLOC_FREE
bytearray_t* byte_array_create(int size)
{
	bytearray_t* byarray = (bytearray_t*)gusConfig.malloc(sizeof(bytearray_t));
	u8* data = NULL;
	if (byarray == NULL)
	{
		goto CREATE_ERROR;
	}
	data = (u8*)gusConfig.malloc(size);
	if (data == NULL)
	{
		goto CREATE_ERROR;
	}
	byte_array_init(byarray, data, size);
	return byarray;
CREATE_ERROR:
	if (byarray != NULL)
	{
		gusConfig.free(byarray);
	}
	if (data != NULL)
	{
		gusConfig.free(data);
	}
	return NULL;
}

void byte_array_free(bytearray_t* byarr)
{
	if (byarr != NULL)
	{
		if (byarr->data != NULL)
		{
			gusConfig.free(byarr->data);
		}
		gusConfig.free(byarr);
	}
}
#endif 

/*
* 返回压入的长度
* 返回0表示数据已满,不能压入
*/
int byte_array_push_byte(bytearray_t* byarr, u8 byt)
{
	if (byarr->len + 1 > byarr->size)
	{
		return 0;
	}
	byarr->data[byarr->len] = byt;
	byarr->len += 1;
	return 1;
}
/*
 * return free memory size
 */
int byte_array_push_byte_ret_free(bytearray_t* byarr, u8 byt)
{
	if (byarr->len + 1 > byarr->size)
	{
		return -1;
	}
	byarr->data[byarr->len] = byt;
	byarr->len += 1;
	return byarr->size - byarr->len;
}
int byte_array_push_bytes(bytearray_t* byarr, int count, const u8* byts)
{
	// 空闲长度
	int free_len = byarr->size - byarr->len;
	if (free_len < count)
	{
		return 0;
	}
	memcpy(byarr->data + byarr->len, byts, count);
	byarr->len += count;
	return count;
}
int byte_array_clear(bytearray_t* byarr)
{
	int temp = byarr->len;
	byarr->len = 0;
	return temp;
}
int byte_array_pop(bytearray_t* byarr, int count)
{
	if (count >= byarr->len)
	{
		return byte_array_clear(byarr);
	}
	byarr->len -= count;
	return  count;
}
int byte_array_vserial(bytearray_t* byarr, const char* format, va_list argp)
{
	int count = memvserializer(byarr->data + byarr->len, format, argp);
	byarr->len += count;
	return count;
}
int byte_array_serial(bytearray_t* byarr, const char* format, ...)
{
    int count = 0;
	va_list argp;
	va_start(argp, format);
	count = byte_array_vserial(byarr, format, argp);
	va_end(argp);
	return count;
}
int byte_array_vserial_pre_cnt(bytearray_t* byarr, const char* format, va_list ap)
{
	int count = 0;
	int len1 = byarr->len;
	int len2 = 0;
	byarr->len += 2;
	count = memvserializer(byarr->data + byarr->len, format, ap);
	if (count == 0)
	{
		return 0;
	}
	byarr->len += count;
	len2 = byarr->len;
	byarr->len = len1;
	byte_array_serial(byarr, "w", count);
	byarr->len = len2;
	return count + 2;
}
int byte_array_serial_pre_cnt(bytearray_t* byarr, const char* format, ...)
{
    int count = 0;
    va_list argp;
	va_start(argp, format);
	count = byte_array_vserial_pre_cnt(byarr, format, argp);
	va_end(argp);
	return count;
}

int byte_array_unvserial(const bytearray_t* ba, int start, const char* format, va_list argp )
{
    return memvunserializer(ba->data + start, format, argp);
}
int byte_array_unserial(const bytearray_t* ba, int start, const char* format, ...)
{
    int index = 0;
    va_list argp;
    va_start(argp, format);
    index = byte_array_unvserial(ba, start, format, argp);
    va_end(argp);
    return index;
}


